package org.example.aienglishapp.config.login;

import org.example.aienglishapp.entity.login.Permission;
import org.example.aienglishapp.entity.login.Role;
import org.example.aienglishapp.entity.login.User;
import org.example.aienglishapp.mapper.login.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

import lombok.extern.slf4j.Slf4j;

/**
 * 自定义用户详情服务类。
 *
 * 该类实现了 {@link UserDetailsService} 接口，用于根据用户名加载用户详细信息，
 * 包括用户的认证信息（如密码）和授权信息（如角色和权限）。这些信息用于 Spring Security 进行身份验证和访问控制。
 *
 * @author xlj
 * @since 2024-10-1
 * @version 1.0
 */
@Slf4j
@Service
public class CustomUserDetailsService implements UserDetailsService {

    @Autowired
    private UserMapper userMapper;

    /**
     * 根据用户名加载用户详细信息。
     *
     * 此方法用于查找指定用户名的用户，并构建包含用户认证和授权信息的 UserDetails 对象。
     * 如果未找到对应的用户，则抛出 UsernameNotFoundException 异常。
     *
     * @param username 用户名
     * @return 返回包含用户认证和授权信息的 UserDetails 对象
     * @throws UsernameNotFoundException 如果找不到指定用户名的用户
     */
    @Override
    @Transactional
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        log.info("正在加载用户名为: {} 的用户", username);

        User user = userMapper.findByUserName(username);
        if (user == null) {
            log.warn("未找到用户名为: {} 的用户", username);
            throw new UsernameNotFoundException("未找到用户名为: " + username + " 的用户");
        }

        log.info("找到用户: {}, 密码: {}", user.getUserName(), user.getUserPassword());

        List<GrantedAuthority> authorities = new ArrayList<>();
        if (user.getRoles() != null) {
            for (Role role : user.getRoles()) {
                // 添加角色
                String roleName = role.getRoleName();
                authorities.add(new SimpleGrantedAuthority("ROLE_" + roleName));

                // 添加角色的权限
                if (role.getPermissions() != null) {
                    for (Permission permission : role.getPermissions()) {
                        String permissionName = permission.getPermissionName();
                        authorities.add(new SimpleGrantedAuthority("PERMISSION_" + permissionName));
                    }
                }
            }
        }

        log.info("返回 UserDetails，包含角色和权限: {}", authorities);

        return new org.springframework.security.core.userdetails.User(
                user.getUserName(),
                user.getUserPassword(),
                authorities
        );
    }
}